<?php

namespace Anchu\Restful\Controllers;

use Anchu\Restful\Models\Model;
use Anchu\Restful\Repository\Repository;
use Anchu\Restful\Runner\Decorates\DataUnSensibleDecorate;
use Anchu\Restful\Runner\Decorates\FilterDecorate;
use Anchu\Restful\Runner\Decorates\FilterUserIdDecorate;
use Anchu\Restful\Runner\ExportRunner;
use Anchu\Restful\Runner\IndexRunner;
use Anchu\Restful\Runner\Runner;
use Anchu\Restful\Runner\ViewRunner;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Routing\Route;

class RestController extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;

    public string $model = "";
    public string $repository = "Anchu\Restful\Repository\Repository";
    public string $auth = "api";

    /**
     * @return \string[][]
     * @example: 如果没有赋值，则会使用默认值，默认值参考__call()
     */
    public function actions()
    {
        return [
            'index' => [
                'request' => Request::class, // 数据格式校验
                'repository' => Repository::class, // 查询构建
                'runner' => IndexRunner::class,
                'decorates' => [
                    'filters' => [
                        FilterDecorate::class, // 获取检索条件，组件sql
                        //FilterUserIdDecorate::class,
                    ],
                    'before' => [],
                    'after' => [
                        DataUnSensibleDecorate::class, // 手机、身份证脱敏
                    ],
                ],
            ],
            'view' => [
                'request' => Request::class, // 数据格式校验
                'repository' => Repository::class, // 查询构建
                'runner' => ViewRunner::class,
                'decorates' => [
                    'filters' => [
                        FilterDecorate::class,
                        //FilterUserIdDecorate::class,
                    ],
                    'before' => [],
                    'after' => [
                        DataUnSensibleDecorate::class, // 手机、身份证脱敏
                    ],
                ],
            ],
            'create' => [
                'request' => Request::class, // 数据格式校验
                'repository' => Repository::class, // 查询构建
                'runner' => ViewRunner::class,
                'decorates' => [
                    'filters' => [
                        FilterDecorate::class,
                        FilterUserIdDecorate::class,
                    ],
                    'before' => [],
                    'after' => [],
                ],
            ],
            'update' => [
                'request' => Request::class, // 数据格式校验
                'repository' => Repository::class, // 查询构建
                'runner' => ViewRunner::class,
                'decorates' => [
                    'filters' => [
                        FilterDecorate::class,
                        FilterUserIdDecorate::class,
                    ],
                    'before' => [],
                    'after' => [],
                ],
            ],
            'delete' => [
                'request' => Request::class, // 数据格式校验
                'repository' => Repository::class, // 查询构建
                'runner' => ViewRunner::class,
                'decorates' => [
                    'filters' => [
                        FilterDecorate::class,
                        FilterUserIdDecorate::class,
                    ],
                    'before' => [],
                    'after' => [],
                ],
            ],
            'export' => [
                'request' => Request::class, // 数据格式校验
                'repository' => Repository::class, // 查询构建
                'runner' => ExportRunner::class,
                'decorates' => [
                    'filters' => [
                        FilterDecorate::class,
                        //FilterUserIdDecorate::class,
                    ],
                    'before' => [],
                    'after' => [
                        DataUnSensibleDecorate::class, // 手机、身份证脱敏
                    ],
                ],
            ],
        ];
    }

    protected function getRunner($method): Runner
    {
        $actions = $this->actions();
        $className = ucfirst($this->model);
        $actionName = ucfirst($method);
        $auth = ucfirst($this->auth);

        // 先从默认路径中找
        if (class_exists("App\Http\Runner\\{$auth}\\{$className}\\{$actionName}Runner")) {
            $runner = "App\Http\Runner\\{$auth}\\{$className}\\{$actionName}Runner";
        } else if (isset($actions[$method]['runner'])) { // 再从actions配置中找
            $runner = $actions[$method]['runner'];
        } else { // 最后使用默认的值
            $runner = "Anchu\Restful\Runner\\{$actionName}Runner";
        }

        if (!class_exists($runner)) {
            abort('404', '无法找到默认的Runner：$runner');
        }

        return new $runner();
    }

    /**
     * 获取模型类，如果没有设置$model属性的话，默认取控制器名
     * @param string $method
     * @param array $parameters
     * @return \Illuminate\Http\JsonResponse|mixed
     */
    private function getModel() {
        if ($this->model == '') {
            $action = \Route::current()->getActionName();
            list($class, $method) = explode('@', $action);
            $controller = substr(strrchr($class, '\\'), 1);
            $controller = str_replace('Controller', '', $controller);
            return $controller;
        }
        return $this->model;
    }

    public function __call($method, $parameters)
    {
        $actions = $this->actions();
        if (!isset($actions[$method])) {
            parent::__call($method, $parameters);
        } else {
            // TODO: Change the autogenerated stub
            $actions = $this->actions();
            $runner = $this->getRunner($method);
            $repository = $actions[$method]['repository'] ?? $this->repository;

            $model = 'App\Models\\' . ucfirst($this->getModel()) . 'Model';
            if (!class_exists($model)) {
                abort('404', '无法获取模型类: ' . $model);
            }

            $runner->setDecorates($actions[$method]['decorates']);
            $runner->setModel($model);
            $runner->setRepository(new $repository($model));
            $request = isset($actions[$method]['request']) ? app($actions[$method]['request']) : request();
            return $this->success($runner->run($request));
        }
    }

    public function success($data = null)
    {
        $response = [
            'code' => 0,
            'msg' => 'success'
        ];
        if (!is_null($data)) {
            $response['data'] = $data;
        }
        if (request()->method() == "GET" && is_null($data)) {
            $response['data'] = [];
        }

        // 李升琴建议统一返回格式，当根据id获取详情时，及时为空，也需要返回对象格式
        if (request()->route('id', 0) > 0 && (is_null($data) || empty($data))) {
            return response()->json($response, options: JSON_FORCE_OBJECT);
        }

        return response()->json($response);
    }

    public function fail()
    {

    }
}
